# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

# User specific environment
if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
then
    PATH="$HOME/.local/bin:$HOME/bin:$PATH"
fi
export PATH

# 添加相应命令所在路径到环境变量中 
# 先查找 find / -name "命令工具名"
export PATH=~/.npm-global/bin:${PATH}:/usr/local/bin

# [git-remote-gcrypt]()
export  GPG_TTY=$(tty)

# git使用vim
# git config --global core.editor "vim"
export GIT_EDITOR=vim
# 其他的程序也使用vim
export VISUAL=vim
export EDITOR="VISUAL"
PATH=$PATH:$HOME/bin
export PATH

# bash 美化
# 默认: 查看 echo $PS1
# 默认的提示符是显示"[用户名@简写主机名最后所在目录]提示符"
# export PS1='[\u@\h\W]\$'
# 主题样式1:
# export PS1='\e[1;32m\][\e[1m\]\e[5m\]\e[3;35m\]\u\e[0m\]\e[5;34m\]@\e[1;33m\]\H\e[0m\]\e[1;32m\]][\e[1;34m\]\t\e[1;32m\]] \e[1;30m\]\e[3;30m\]\w\e[0m\]\n\$ '
# 主题样式2:
# export PS1='\e[1;32m\][\e[1m\]\e[3;35m\]\u\e[0;34m\]@\e[1;33m\]\H\e[1;32m\]][\e[1;34m\]\t\e[1;32m\]][$([[ $? != 0 ]] && echo -ne "\e[31mFAIL\e[0m" || echo -ne "\e[34mOK\e[0m")\e[1;32m\]] \e[1m\]\e[3;30m\]\w\e[0m\]\n\$ '
# 主题样式3:
# export PS1='\[\033[0;31m\]\342\224\214\342\224\200$([[ $? != 0 ]] && echo "[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200")[\[\033[0;39m\]\u\[\033[01;33m\]@\[\033[01;96m\]\h\[\033[0;31m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;31m\]]\n\[\033[0;31m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]\[\e[01;33m\]\$\[\e[0m\]'
# 主题：极简
# export PS1='\t \u \W  $'
# export PS1='\[\033[0;37m\]\t \[\033[0;31m\]\u \W  \e[1;32m\]$'
# export PS1='\[\033[0;37m\]\t \[\033[0;31m\]\u \e[0;34m\]\W/  \e[1;32m\]$'
# export PS1='\[\033[0;37m\]\t \[\033[0;31m\]\u \e[0;34m\]\W/ $([[ ${git rev-parse --is-inside-work-tree} == true ]] && echo "[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200")  \e[1;32m\]$'

# 主题：显示git分支名
# PS1='\[\033[0;37m\]\t \[\033[0;31m\]\u \e[0;34m\]\W/ \e[0;33m\]$(parse_git_branch) \e[0;32m\]$ \e[1;35m\]'
PS1='\[\033[0;36m\]\u \[\033[0;35m\][\t] \e[0;34m\]\W/ \e[0;33m\]$(parse_git_branch) \e[0;32m\]\n$ \[\033[0;37m\]'

parse_git_branch() {
     git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
     # git rev-parse --is-inside-work-tree 判断是否是git仓库文件夹
}
export PS1

# \e[1;32m\][             加粗绿色显示[
# \e[1m\]\e[3;35m\]\u     加粗斜体紫红色显示用户名
# \e[0;34m\]@             默认样式蓝色显示@
# \e[1;33m\]\H            加粗黄色显示主机名
# \e[1;32m\]][            加粗绿色显示][
# \e[1;34m\]\t            加粗蓝色显示时间
# \e[1;32m\]]             加粗绿色显示]和空格
# \e[1m\]\e[3;30m\]\w     加粗斜体黑色显示工作路径
# \e[0m\]\n\$             清除所有格式，换行显示提示符，注意提示符后有空格

# \[      非打印字符起始，可以用来将终端控制序列嵌入到提示符中
# \]      非打印字符起始结束
# \d：显示曰期，格式为"星期 月 日"。
# \H：显示完整的主机名。如默认主机名"localhost.localdomain"。
# \h：显示简写的主机名。如默认主机名"localhost"。
# \t：显示 24 小时制时间，格式为"HH:MM:SS"。
# \T：显示 12 小时制时间，格式为"HH:MM:SS"。
# \A：显示 24 小时制时间，格式为"HH:MM"。
# @：显示 12 小时制时间，格式为"HH:MM am/pm"。
# \u：显示当前用户名。
# \v：显示 Bash 的版本信息。
# \w：显示当前所在目录的完整名称。
# \W：显示当前所在目录的最后一个目录。
# #：执行的第几条命令。
# $：提示符。如果是 root 用户，则会显示提示符为"#"；如果是普通用户，则会显示提示符为"$"。
# 再比如添加$([[ $? != 0 ]] && echo -ne "\e[31mFAIL\e[0m" || echo -ne "\e[34mOK\e[0m")，显示上一条命令的执行结果
# 官方链接：Controlling the Prompt (Bash Reference Manual)(https://www.gnu.org/savannah-checkouts/gnu/bash/manual/html_node/Controlling-the-Prompt.html)

# ruby
# If you need to have ruby first in your PATH run:
#   echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc
# For compilers to find ruby you may need to set:
#   export LDFLAGS="-L/usr/local/opt/ruby/lib"
#   export CPPFLAGS="-I/usr/local/opt/ruby/include"
export PATH="/usr/local/opt/ruby/bin:$PATH"

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions
if [ -d ~/.bashrc.d ]; then
	for rc in ~/.bashrc.d/*; do
		if [ -f "$rc" ]; then
			. "$rc"
		fi
	done
fi

unset rc

# 加载 补全扩展bash-completion
# Fedora: sudo dnf install bash-completion 
# ArchLinux: sudo pacman -S bash-completion 
[[ $PS1 && -f /usr/share/bash-completion/bash_completion ]] && \
    . /usr/share/bash-completion/bash_completion

# [[ $PS1 && -f ~/.config/scripts/bash-completion-2.11/bash_completion ]] && \
#     . ~/.config/scripts/bash-completion-2.11/bash_completion


# 加载fzf
[ -f ~/.fzf.bash ] && source ~/.fzf.bash

## fzf配置
export FZF_DEFAULT_OPTS="--layout=reverse --inline-info \
                        --height=100% \
                        --header='[tab:复制][Shift-tab:多选][ctrl-w:预览窗位置]' \
                        --header-first \
                        --preview-window="wrap" \
                        --bind='ctrl-w:change-preview-window(hidden|left|down|)' \
                        --bind='tab:execute( echo {}  | pbcopy )+abort' \
                        --cycle \
                        --preview 'bash $HOME/.config/scripts/preview/file_preview.sh {}'"



# export FZF_DEFAULT_OPTS="--height 50% \
#                         --layout=reverse --border \
#                         --preview 'bash $HOME/.config/scripts/preview/file_preview.sh {}'
#                         --preview-window=bottom:5:wrap"
   
if [[ -x "$(which fd)" ]]; then
    ### - 设置使用fd 来查找文件, 并排除了一些项目, 让模糊查找的时候不包括这些项目.
    export FZF_DEFAULT_COMMAND="fd --exclude={.git,.idea,.vscode,.sass-cache,node_modules,build,dist,vendor} --type f"
fi
export FZF_PREVIEW_COMMAND='bash $HOME/.config/scripts/preview/file_preview.sh {}'


# FZF快捷键 
# CTRL-R : 从历史记录中将所选命令粘贴到命令行上
# CTRL-T: 将选定的文件或者目录粘贴到命令行上
# ALT-C cd进入所选目录

# 可通过设置FZF_CTRL_T_COMMAND覆盖默认命令；
# 可通过设置FZF_CTRL_T_OPTS设置其他选项；
# 可通过设置FZF_ALT_C_COMMAND以覆盖默认命令；
# 可通过设置FZF_ALT_C_OPTS设置其他选项；

# 加载 fzf补全扩展 fzf-tab-completion
# [bash的按TAB键自动补全（自动完成）的原理与扩展_คิดถึง643的博客-CSDN博客_tab键补全的原理](https://blog.csdn.net/weixin_72426331/article/details/127332308)
# vim 编辑时的补全，补全来源 "[File]", "[Dir]" 字段很好的说明了这一点。参考视频 https://www.semicolonandsons.com/episode/vim-autocomplete-overview 1 分 10 秒左右内容。

# [使用fzf完成tab补全](https://github.com/lincheney/fzf-tab-completion
if [[ -f ~/.config/scripts/fzf-tab-completion/bash/fzf-bash-completion.sh ]] ;
then
    source ~/.config/scripts/fzf-tab-completion/bash/fzf-bash-completion.sh
    bind -x '"\t": fzf_bash_completion'
fi

## z.lua 配置
### ZSH 初始化
if [[ -d ~/.config/z.lua/z.lua ]]; then
    eval "$(lua ~/.config/z.lua/z.lua  --init bash once enhanced)"
else
    git clone  --depth 1 https://ghproxy.com/https://github.com/skywind3000/z.lua  ~/.config/z.lua
fi

# - 设置 `$_ZL_CMD` 来改变命令名称 (默认为 z)。
# - 设置 `$_ZL_DATA` 来改变数据文件 (default ~/.zlua)。
# - 设置 `$_ZL_NO_PROMPT_COMMAND` 为 1 来跳过钩子函数初始化（方便自己处理）。
# - 设置 `$_ZL_EXCLUDE_DIRS` 逗号分隔的路径列表，列表内的路径不会被收集。
# - 设置 `$_ZL_ADD_ONCE` 为 '1' 时，仅在当前路径 `$PWD` 改变时才更新数据库。
# - 设置 `$_ZL_MAXAGE` 来确定一个数据老化的阀值 (默认为 5000)。
# - 设置 `$_ZL_CD` 用来指定你想用的 cd 命令，比如有人用 cd_func 。
# - 设置 `$_ZL_ECHO` 为 1 可以在跳转后显示目标路径名称。
# - 设置 `$_ZL_MATCH_MODE` 为 1 可以打开 “增强匹配模式”。
# - 设置 `$_ZL_HYPHEN` 为 1 可以允许关键字中包含横线 （横线默认是 lua 正则关键字，要转写成 `%-`）。

alias zh='z -I -t .'   # 回到历史路径，用 fzf 进行历史路径操作
alias zi='z -i'        # 使用交互式选择模式
alias zf='z -I'        # 使用 fzf 对多个结果进行选择
alias zb='z -b'        # 快速回到父目录

# 自定义命令
# 使用cd fd fzf 查找与切换vim文件
vimf(){
    vim $(fzf --preview 'cat {}')
}
nvimf(){
    nvim $(fzf --preview 'cat {}')
}

# 使用cd fd fzf 查找与切换目录
cdf(){
   # cd $(fd -p '/' -t d | fzf )
   # cd $(fd -p ’/‘ -t d | fzf --preview 'ls -alh {}')
   cd $(fd  -t  d | fzf --preview 'ls -ahl {}' )
}

if [[ -d ~/.cargo/env ]];then
	. "$HOME/.cargo/env"
fi

# 自定义命令
# 使用cd fd fzf 查找与切换vim文件
vimf(){
    # vim $(fzf --preview  'cat -n {}')
    # 加 --multi 可按tab 多选 
    # 加 --cycle 选项循环
    # vim $(fzf --multi --preview  'cat -n {}')
    vim $(fzf --multi --cycle --header=请选择（tab可多选） --preview  'bash $HOME/.config/scripts/preview/file_preview.sh {}')
}


nvimf(){
    # nvim $(fzf --preview  'cat -n {}')
    nvim $(fzf --multi --cycle --header=请选择（tab可多选）  'cat -n {}')
}

# 使用cd fd fzf 查找与切换目录
cdf(){
   # cd $(fd -p '/' -t d | fzf )
   # cd $(fd -p ’/‘ -t d | fzf --preview 'ls -alh {}')
   # cd $(fd  -t  d | fzf --preview 'ls -ahl {}' )
   cd $(fd  -t  d | fzf)
}
alias fcd="cdf"

fmpv(){
  # 加 --multi 可按tab 多选
  # 加 --cycle 选项循环
  mpv $(fd  -e mp4 -e avi | fzf --cycle --preview 'ls -ahl {}' ) 
}

# fzf mpc
fmui(){
  ~/.config/scripts/fmui/fmui
}

# fzf *.desktop launcher
fdesktoplauncher(){
  ~/.config/scripts/fdesktopui.sh
}
alias fl="fdesktoplauncher"
alias flauncher="fdesktoplauncher"

# fzf menu
fmenu(){
  ~/.config/scripts/menu/menumenu fzf
}
alias fm="fmenu"

# rofi menu
rmenu(){
  ~/.config/scripts/menu/menumenu rofi
}
alias fm="fmenu"

# dmenu menu
dmenumenu(){
  ~/.config/scripts/menu/menumenu dmenu
}
alias dm="dmenumenu"

alias fscp=~/.config/scripts/fzf-sshscp/scp.sh
alias fssh=~/.config/scripts/fzf-sshscp/ssh.sh
alias fsql=~/.config/scripts/fzf-sshscp/ssh.sh
alias demo=~/.config/scripts/demo.sh



# 使用 cd find fzf 查找与切换目录
ffcd() {
  local dir
  dir=$(find ${1:-.} -path '*/\.*' -prune \
                  -o -type d -print 2> /dev/null | fzf +m) &&
  cd "$dir"
}

# 会自动出现当前目录的 fzf，选择文件之后回车即可用默认 $EDITOR 打开文件
fe() {
  local files
  IFS=$'\n' files=($(fzf-tmux --query="$1" --multi --select-1 --exit-0))
  [[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}"
}

# 使用  fzf 查找与切换tmux
# tm - create new tmux session, or switch to existing one. Works from within tmux too. (@bag-man)
# `tm` will allow you to select your tmux session via fzf.
# `tm irc` will attach to the irc session (if it exists), else it will create it.
ftm() {
  [[ -n "$TMUX" ]] && change="switch-client" || change="attach-session"
  if [ $1 ]; then
    tmux $change -t "$1" 2>/dev/null || (tmux new-session -d -s $1 && tmux $change -t "$1"); return
  fi
  session=$(tmux list-sessions -F "#{session_name}" 2>/dev/null | fzf --exit-0) &&  tmux $change -t "$session" || echo "No sessions found."
}


# fs [FUZZY PATTERN] - Select selected tmux session
#   - Bypass fuzzy finder if there's only one match (--select-1)
#   - Exit if there's no match (--exit-0)
fs() {
  local session
  session=$(tmux list-sessions -F "#{session_name}" | \
    fzf --query="$1" --select-1 --exit-0) &&
  tmux switch-client -t "$session"
}

# fkill - kill process
fkill() {
  local pid
  pid=$(ps -ef | sed 1d | fzf -m | awk '{print $2}')

  if [ "x$pid" != "x" ]
  then
    echo $pid | xargs kill -${1:-9}
  fi
}

# 切换git分支
alias fgco='git checkout ${$(git branch --remote | fzf)#"origin/"}'

# merge指定分支内容
alias fgm='git merge ${$(git branch --remote | fzf)#"origin/"}'

# fzf 、git git log  组合
fgl(){
    # git log --no-merges --color --graph --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Cblue %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit
    # git log --oneline | fzf | grep -o -E "^[0-9a-z]+" | xargs -I {} git show {}
    git log --no-merges --graph --date=format:'%Y-%m-%d %H:%M:%S' \
            --pretty=format:'%h - %d% %s (%cd) <%an>' \
            --abbrev-commit \
            | fzf --cycle | awk -F - '{print $1}'| grep -o -E "[0-9a-z]+"  | xargs -I {} git show {}
    # 加 --cycle 选项循环
}
alias gl="git log --no-merges --color --graph --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Cblue %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit"

# fzf 、git git log  、git checkout 组合
fglc(){
    # git log --no-merges --color --graph --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Cblue %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit
    # git log --oneline | fzf | grep -o -E "^[0-9a-z]+" | xargs -I {} git checkout {}
    git log --no-merges --graph --date=format:'%Y-%m-%d %H:%M:%S' \
            --pretty=format:'%h - %d% %s (%cd) <%an>' \
            --abbrev-commit \
            | fzf --cycle | awk -F - '{print $1}'| grep -o -E "[0-9a-z]+"  | xargs -I {} git checkout {}
    # 加 --cycle 选项循环
}

# fzf 、git status -s 、git add 组合
fga(){
  # 加 --cycle 选项循环
  # 加 --multi 可按tab 多选
  # git status -s | fzf --multi --preview 'bat  $( echo {} | awk -F " " '{print $2}') ' | awk -F ' ' '{print $2}'  | xargs -I {} git add {}
  git status -s | fzf --cycle --multi --header=请选择（tab多选） --preview 'git diff --cached $(echo {} | tr -s " " | cut -d " " -f 2)' | awk -F ' ' '{print $2}'  | xargs -I {} git add {}

}


# fzf greenclip
grf(){
    # greenclip print | sed '/^$/d' | fzf -e | xargs -r -d'\n' -I '{}' greenclip print '{}'
    greenclip print | sed '/^$/d' | fzf -e | xargs -r -d'\n' -I '{}' greenclip print '{}'; sleep 0.5; xdotool type $(xclip -o -selection clipboard)
}

# dmenu greenclip
grd(){
    # greenclip print | sed '/^$/d' | dmenu -i -l 10 -p clipboard | xargs -r -d'\n' -I '{}' greenclip print '{}'
    greenclip print | sed '/^$/d' | dmenu -i -l 10 -p clipboard | xargs -r -d'\n' -I '{}' greenclip print '{}';sleep 0.5; xdotool type $(xclip -o -selection clipboard)
}

#  greenclip clear
grc(){
    pkill greenclip && greenclip clear && greenclip daemon &
}


## 终端命令行查英语单词
v2(){
  declare q="$*";
  #curl --user-agent curl "https://v2en.co/${q// /%20}";
  curl --user-agent curl "https://d.supjohn.com/${q// /%20}";

}
## v2-sh 可以直接进入交互模式，不用重复输入 v2 前缀
v2-sh(){
  while echo -n "v2en>";
  read -r input;
  [[ -n "$input" ]]
  do v2 "$input";
  done
}


# ranger 配置
## 会自动切换到最后一次浏览的目录.
# rangerhistory(){
ranger_cd() {
    temp_file="$(mktemp -t "ranger_cd.XXXXXXXXXX")"
    # ranger --choosedir="$temp_file" -- "${@:-$PWD}"        # 退出ranger后不会切换到最后停留的目录地址
    source ranger --choosedir="$temp_file" -- "${@:-$PWD}"   # 退出ranger后会切换到最后停留的目录地址
    if chosen_dir="$(cat -- "$temp_file")" && [ -n "$chosen_dir" ] && [ "$chosen_dir" != "$PWD" ]; then
        cd -- "$chosen_dir"
    fi
    rm -f -- "$temp_file"
}

# 使用rg和fzf搭配递归查找当前文件夹下内容
rg_fzf_find()
{
    # rg --column --smart-case  -- '' | fzf
    # rg --column --smart-case  -- '' | fzf --preview 'cat -n $( echo {} | cut -d : -f 1)'
    result=`rg --column --smart-case  -- '' | fzf --preview 'bat  $( echo {} | cut -d : -f 1)   --color=always  --wrap=auto  --style=numbers  --highlight-line=$(echo {} | cut -d : -f 2):$(echo {} | cut -d : -f 2)  --line-range=$(( $(( $(echo {} | cut -d : -f 2)-18 ))>18?$(( $(echo {} | cut -d : -f 2)-18 )):1 )):$(( $(echo {} | cut -d : -f 2)+18 ))  '`
    # echo "[Debug]=======${result}"
    if [ -f "$(echo ${result} | cut -d : -f 1)" ]; then
        vim  -o $(echo ${result} | cut -d : -f 1) + $(echo ${result} | cut -d : -f 2) 
    else
        echo "取消选择"
    fi
}

# rg 参数说明
# -M --max-depth 限制文件夹递归搜索深度。rg --max-depth 0 dir/则不执行任何搜索；rg --max-depth 1 dir/只在dir/当前目录中进行搜索。

# 使用ack和fzf搭配递归查找当前文件夹下内容
ack_fzf_find()
{
    # ack foo --js -A 2 -B 2 # 在当前目录下，查找js文件中包含foo文本，并打印与其相关的上下2行
    result=`ack -- '' | fzf --preview 'bat  $( echo {} | cut -d : -f 1)   --color=always  --wrap=auto  --style=numbers  --highlight-line=$(echo {} | cut -d : -f 2):$(echo {} | cut -d : -f 2)  --line-range=$(( $(( $(echo {} | cut -d : -f 2)-18 ))>18?$(( $(echo {} | cut -d : -f 2)-18 )):1 )):$(( $(echo {} | cut -d : -f 2)+18 ))  '`
    # echo "[Debug]=======${result}"
    # vim -o $(echo ${result} | cut -d : -f 1) +$(echo ${result} | cut -d : -f 2)
    if [ -f "$(echo ${result} | cut -d : -f 1)" ]; then
        vim -o $(echo ${result} | cut -d : -f 1) + $(echo ${result} | cut -d : -f 2) 
    else
        echo "取消选择"
    fi
}

alias r='ranger'
alias rc='source ranger'  # 退出ranger后会切换到最后停留的目录地址
alias rh='ranger_cd'

# 设置命令通用别名
alias cls='clear'
alias ll='ls -l'
alias la='ls -a'
alias vi='vim'
alias javac="javac -J-Dfile.encoding=utf8"
alias grep="grep --color=auto"

# 复制/黏贴 
# 安装 xclip / xsel （linux 需要 X ）
#  Debian、Ubuntu、Linux Mint 上： sudo apt install xclip xsel
#  Arch Linux ：sudo pacman xclip xsel
#  Fedora ： sudo dnf xclip xsel

# alias pbcopy='xsel --clipboard --input'
# alias pbpaste='xsel --clipboard --output'

# alias pbcopy='xclip -selection clipboard'
# alias pbpaste='xclip -selection clipboard -o'

# termux要支持与系统复制粘贴安装如下：
# pkg install termux-api
alias pbcopy='termux-clipboard-set' 
alias pbpaste='termux-clipboard-get'

# [技术|如何在 Linux 上使用 pbcopy 和 pbpaste 命令](https://linux.cn/article-9917-1.html)
